home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / STRING.C < prev    next >
C/C++ Source or Header  |  1992-08-11  |  27KB  |  697 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Created: MBN 06/27/89 -- Initial design and implementation
  13. // Updated: DKM 07/07/89 -- To work around Xenix 31 char limit:
  14. //                          Shortened is_less_than        to is_lt
  15. //                                    is_greater_than     to is_gt
  16. //                                    is_less_or_equal    to is_le
  17. //                                    is_greater_or_equal to is_ge
  18. //                          Removed is_equal_or_less and is_greater_or_less
  19. // Updated: MBN 09/07/89 -- Added conditional exception handling
  20. // Updated: MBN 09/26/89 -- Fixed bug to set size when growth size ratio given
  21. // Updated: LGO 10/11/89 -- Removed operator>>
  22. // Updated: MBN 10/24/89 -- Fixed backwards comparison in is_lt and is_gt
  23. // Updated: LGO 10/28/89 -- Removed is_lt, is_gt, is_le, is_ge, is_equal
  24. //                          and is_not_equal (use char* functions instead)
  25. // Updated: LGO 01/03/90 -- Avoid use of strncat
  26. // Updated: LGO 01/03/90 -- Re-write trim, right_trim, left_trim, upcase,
  27. //                          downcase, capitalize, insert, replace, yank,
  28. //                          sub_string, and strncpy to reduce heap allocation
  29. // Updated: LGO 01/04/90 -- Delay memory allocation (see Empty_String_g)
  30. // Updated: MJF 03/12/90 -- Added group names to RAISE
  31. // Updated: DLS 03/22/91 -- New lite version
  32. // Updated: JAM 08/11/92 -- removed DOS specifics, stdized #includes
  33. // Updated: JAM 08/11/92 -- added static data member def
  34. //
  35. // This file contains  member and  friend function implementation code  for the
  36. // CoolString  class defined in the String.h   header file.   Where appropriate and
  37. // possible,  interfaces to,  and us  of,   existing  system functions has been
  38. // incorporated. An overview of the structure of the CoolString class, along with a
  39. // synopsis of each member  and friend function, can be  found  in the String.h
  40. // header file.
  41. //
  42.  
  43. #ifndef STRINGH                    // If class not been defined
  44. #include <cool/String.h>            // Include class header file
  45. #endif
  46.  
  47. #include <ctype.h>        // Include character processing macros
  48.  
  49.  
  50. char* Empty_String_g = "";        // Used to allocate empty CoolStrings
  51.                     // this allows operator char* to work
  52.  
  53. // update_memory -- Private method to perform common memory check/adjustment
  54. // Input:           CoolString reference, pointer to initial CoolString value
  55. // Output:          None
  56.  
  57. void update_memory (CoolString& s) {
  58.   long size = s.size;
  59.   if (s.growth_ratio != 0.0) {        // If a growth ratio is set
  60.     size = long(size * (1.0 + s.growth_ratio)); // Get new size
  61.     if (size < s.length)        // But if this is still not big enough
  62.       size = s.length;            // grow to big enough size
  63.   }
  64.   else if ((s.length - size) < s.alloc_size_s) // If small growth factor
  65.     size += s.alloc_size_s;        // Increment by allocation size
  66.   else                    // Else adding lots of characters
  67.     size = s.length;            // so grow to bigger size
  68.   s.resize(size);            // Grow the String
  69. }
  70.  
  71.  
  72. // CoolString() -- Simple constructor for a string object. Memory is allocated
  73. //             for the char* pointer of size MEM_BLK_SIZE
  74. // Input:      None
  75. // Output:     CoolString reference
  76.  
  77.  
  78. CoolString::CoolString () {            
  79.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  80.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  81.   this->growth_ratio = 0.0;        // Initialize growth ratio
  82.   this->length = 0;            // Zero characters in string
  83.   this->size = 0;            // Size of allocated block 
  84.   this->str = Empty_String_g;        // No memory allocated
  85. }
  86.  
  87.  
  88. // CoolString(char) -- Constructor to initialize a string object with a char
  89. // Input:          character
  90. // Output:         CoolString reference to new object
  91.  
  92. CoolString::CoolString (char c) {    
  93.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  94.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  95.   this->growth_ratio = 0.0;        // Initialize growth ratio
  96.   this->length = 1;            // Length of character is 1
  97.   this->size = this->length+1;        // Size of allocated block
  98.   this->str = new char[size];        // Allocate memory for string
  99.   *this->str = c;            // Assign character
  100.   *(this->str+1) = END_OF_STRING;    // END_OF_STRING terminator for string
  101. }
  102.  
  103.  
  104. // CoolString(char*) -- Constructor to initialize a string object with a char*
  105. // Input:           char* pointer
  106. // Output:          CoolString reference to new object
  107.  
  108. CoolString::CoolString (const char* c) { 
  109.   if (this->alloc_size_s == 0)         // If allocation size is uninitialized
  110.     this->alloc_size_s = MEM_BLK_SZ;     // Set memory block allocation size
  111.   this->growth_ratio = 0.0;         // Initialize growth ratio
  112.   this->length = strlen (c);         // Determine length of string
  113.   this->size = this->length+1;         // Size of allocated block
  114.   this->str = new char[size];         // Allocate memory for string
  115.   strcpy ((char *)this->str, c);     // Copy characters 
  116. }
  117.  
  118.  
  119. // CoolString(CoolString&) -- Constructor to initialize a string object to
  120. //                    that of another String.
  121. // Input:             CoolString reference
  122. // Output:            CoolString reference to new object
  123.  
  124. CoolString::CoolString (const CoolString& s) { 
  125.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  126.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  127.   this->growth_ratio = s.growth_ratio;    // Initialize growth ratio
  128.   this->length = s.length;        // length of character string
  129.   if (s.length > 0) {
  130.     this->str = new char[s.size];    // Allocate memory for string
  131.     strcpy ((char *)this->str, s.str);    // Copy characters
  132.     this->size = s.size;        // Size of allocated block
  133.   }
  134.   else {
  135.     this->str = Empty_String_g;        // Don't allocate when empty
  136.     this->size = 0;
  137.   }
  138. }
  139.  
  140.  
  141. // CoolString(char*, size) -- Constructor to initialize a string object with
  142. //                        a char* and provide an initial size value
  143. // Input:                 char* pointer and size value
  144. // Output:                CoolString reference to new object
  145.  
  146. CoolString::CoolString (const char* c, long sz) {
  147.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  148.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  149.   this->length = strlen (c);        // Determine length of character string
  150.   if (this->length > sz)        // If initial string is larger
  151.     this->size = length+1;        // Size of allocated block
  152.   else
  153.     this->size = sz+1;            // Size of allocated block
  154.   this->str = new char[size];        // Allocate memory for string 
  155.   strcpy ((char *)this->str, c);    // Copy characters
  156. }
  157.  
  158.  
  159. // CoolString(CoolString&, long) -- Constructor to initialize a string
  160. //                          object with a String and provide
  161. //                          an initial block size value
  162. // Input:                   CoolString reference and size value
  163. // Output:                  CoolString reference to new object
  164.  
  165. CoolString::CoolString (const CoolString& s, long sz) { 
  166.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  167.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  168.   this->length = s.length;        // Determine length of character string
  169.   if (this->length > sz)        // If initial string is larger
  170.     this->size = length+1;        // Size of allocated block
  171.   else
  172.     this->size = sz+1;            // Size of allocated block
  173.   this->str = new char[size];        // Allocate memory for string
  174.   strcpy ((char *)this->str, s.str);    // Copy characters over
  175. }
  176.  
  177.  
  178. // ~CoolString() -- CoolString object destructor
  179. // Input:       CoolString object
  180. // Output:      None
  181.  
  182. CoolString::~CoolString () {            // CoolString object destructor
  183.   if (this->str != Empty_String_g)
  184.     delete this->str;            // Deallocate string memory
  185. }
  186.  
  187.  
  188. // clear -- Flush the character string from the string object by setting
  189. //          the char* pointer to NULL and the length to zero.
  190. // Input:   this* 
  191. // Output:  None
  192.  
  193. void CoolString::clear() {
  194.   *(this->str) = NULL;                // Clear this CoolString by using NULL
  195.   this->length = 0;            // Set new string length
  196. }
  197.  
  198.  
  199. // strcpy -- CoolString copy of a single character to a CoolString object
  200. // Input:    CoolString reference and a character
  201. // Output:   CoolString object containing a character string
  202.  
  203. CoolString& strcpy (CoolString& s, char c) {
  204.   if (s.size < 2) {            // Allocate memory block
  205.     if (s.str != Empty_String_g)    // When memory allocated
  206.       delete s.str;            // Delete block
  207.     s.size = s.alloc_size_s;        // Size of allocated block
  208.     s.str = new char[s.size];        // Allocate memory for string
  209.   }
  210.   s.length = 1;                // Character string length
  211.   *(s.str) = c;                // Assign character
  212.   *(s.str+1) = END_OF_STRING;        // END_OF_STRING terminator for string
  213.   return s;                // Return CoolString reference
  214. }  
  215.  
  216.  
  217. // strcpy -- CoolString copy of a char* to a CoolString object
  218. // Input:    CoolString reference and a char* 
  219. // Output:   CoolString object containing a character string
  220.  
  221. CoolString& strcpy (CoolString& s, const char *c) {
  222.   s.length = strlen (c);        // Determine length of character string
  223.   if (s.size <= s.length)        // If not enough memory allocated
  224.     update_memory (s);            // Adjust/update memory if necessary
  225.   strcpy (s.str, c);            // Else just copy new string value
  226.   return s;                // Return CoolString reference
  227. }
  228.  
  229.  
  230. // strcpy -- CoolString copy of one CoolString object to another. 
  231. // Input:    Two CoolString references
  232. // Output:   Updated CoolString object 
  233.  
  234. CoolString& strcpy (CoolString& s1, const CoolString& s2) {
  235.   s1.length = s2.length;        // Determine length of character string
  236.   if (s1.size > s2.length &&        // If string fits in allocated memory
  237.       s1.str != Empty_String_g)        // and s1 has memory allocated
  238.     strcpy (s1.str, s2.str);        // Copy string value
  239.   else {
  240.     if (s1.str != Empty_String_g)    // When memory allocated
  241.       delete s1.str;            // Delete block
  242.     if (s2.length == 0) {
  243.       s1.str = Empty_String_g;        // Don't allocate when empty
  244.       s1.size = 0;
  245.     }
  246.     else {
  247.       s1.size = s2.length+1;        // Set new block size
  248.       s1.str = new char[s1.size];    // Allocate new block of memory
  249.       strcpy (s1.str, s2.str);        // Copy string value
  250.     }
  251.   }
  252.   return s1;                // Return string reference
  253. }
  254.  
  255. // strcat -- Concatenate a single character to a CoolString object
  256. // Input:    CoolString reference and a character
  257. // Output:   CoolString object concatenated with character 
  258.  
  259. CoolString& strcat (CoolString& s, char c) {
  260.   s.length += 1;            // Determine length of new string
  261.   if (s.size <= s.length)        // If not enough allocated memory
  262.     update_memory (s);            // Adjust/update memory if necessary
  263.   s.str[s.length-1] = c;        // Append new character
  264.   s.str[s.length] = END_OF_STRING;    // END_OF_STRING terminator
  265.   return s;                // Return CoolString
  266. }
  267.  
  268.  
  269. // strcat -- Concatenate a CoolString and a char*
  270. // Input:    CoolString reference and a char*
  271. // Output    CoolString object concatentated with character string
  272.  
  273. CoolString& strcat (CoolString& s, const char* c) {
  274.   long start_length = s.length;         // Find initial string length
  275.   s.length += strlen (c);        // Determine length of new string
  276.   if (s.size <= s.length)        // If not enough allocated memory
  277.     update_memory (s);            // Adjust/update memory if necessary
  278.   strcpy (s.str+start_length, c);    // Concatenate characters   
  279.   return s;                // Return CoolString
  280. }
  281.  
  282.  
  283. // strncat -- Concatentate a CoolString with "n" characters from char*
  284. // Input:     CoolString reference, char*, number of characters
  285. // Output:    CoolString object concatenedate with "n" characters
  286.  
  287. CoolString& strncat (CoolString& s, const char* c, int n) {
  288. #if ERROR_CHECKING
  289.   if (n < 0) {                // If invalid length specified
  290.     printf ("CoolString::strncat(): Negative length %d.\n", n);
  291.     exit (1);
  292.   }
  293. #endif
  294.   long start_length = s.length;        // Find initial string length
  295.   s.length += n;            // Determine length of new string
  296.   if (s.size <= s.length)        // If not enough allocated memory
  297.     update_memory (s);            // Adjust/update memory if necessary
  298.   strncpy (s.str+start_length, c, size_t(n));    // Concatenate characters 
  299.   return s;                // Return CoolString
  300. }
  301.  
  302.  
  303. // strcat -- Concatenate two CoolString objects
  304. // Input:    Two CoolString references
  305. // Output:   CoolString object concatenated with CoolString object
  306.  
  307. CoolString& strcat (CoolString& s1, const CoolString& s2) {
  308.   long start_length = s1.length;
  309.   s1.length += s2.length;        // Determine length of new string
  310.   if (s1.size <= s1.length)        // If not enough allocated memory
  311.     update_memory (s1);            // Adjust/update memory if necessary
  312.   strcpy (s1.str+start_length, s2.str); // Concat characters   
  313.   return s1;                // Return CoolString
  314. }
  315.  
  316.  
  317. // strncat -- Concatentate a CoolString with "n" characters from a CoolString
  318. // Input:     Two CoolString references and number of characters
  319. // Output:    CoolString object concatenedate with "n" characters
  320.  
  321. CoolString& strncat (CoolString& s1, const CoolString& s2, int n) {
  322. #if ERROR_CHECKING
  323.   if (n < 0) {                // If invalid length specified
  324.     printf ("CoolString::strncat(): Negative length %d.\n", n);
  325.     exit (1);
  326.   }
  327. #endif
  328.   long start_length = s1.length;        // Find initial string length
  329.   s1.length += n;            // Determine length of new string
  330.   if (s1.size <= s1.length)        // If not enough allocated memory
  331.     update_memory (s1);            // Adjust/update memory if necessary
  332.   strncpy (s1.str+start_length, s2.str, size_t(n)); // Concat chars 
  333.   return s1;                // Return CoolString
  334. }
  335.  
  336.  
  337. // reverse -- Reverse the order of the characters in CoolString object
  338. // Input:     CoolString object
  339. // Output:    CoolString object with character order reverse
  340.  
  341. void CoolString::reverse () {
  342.   char c;                    // Temporary variable
  343.   for (long i = 0, j = this->length-1;        // Counting from front and rear
  344.        i < this->length / 2; i++, j--) {    // until we reach the middle
  345.     c = this->str[i];                // Save front character
  346.     this->str[i] = this->str[j];        // Switch with rear character
  347.     this->str[j] = c;                // Copy new rear character
  348.   }
  349. }
  350.  
  351.  
  352. // resize -- Adjust the memory size of a string to accomodate some size
  353. // Input:    CoolString object
  354. // Output:   None
  355.  
  356. void CoolString::resize (long sz) {
  357. #if ERROR_CHECKING
  358.   if (sz < 0) {                // If invalid size
  359.     printf ("CoolString::resize(): Negative resize %d.\n", sz);
  360.     exit (1);
  361.   }
  362. #endif
  363.   char* temp = this->str;        // Save pointer to existing string
  364.   this->size = sz+1;            // Save size of allocated memory
  365.   this->str = new char[sz+1];        // Allocate memory for desired size
  366.   strcpy ((char *)this->str, temp);    // Copy original string back
  367.   if (temp != Empty_String_g)
  368.     delete temp;            // Deallocate old memory
  369. }
  370.  
  371.  
  372. // operator<< -- Overload output operator for CoolString objects
  373. // Input:        CoolString reference
  374. // Output:       Formatted output and stream descriptor
  375.  
  376. ostream& operator<< (ostream& os, const CoolString& s) {
  377.   return os << s.str;                // Output char* and newline
  378. }
  379.  
  380.  
  381. // operator<< -- Overload output operator for string objects
  382. // Input:        CoolString pointer
  383. // Output:       Formatted output and stream descriptor
  384.  
  385. ostream& operator<< (ostream& os, const CoolString* s) {
  386.   return operator<< (os, *s);
  387. }
  388.  
  389.  
  390. // strtol -- Returns as a long integer the value represented by the
  391. //           CoolString pointer to by s, scanning upto the first character
  392. //           that is inconsistent with the base. Leading white space is
  393. //           ignored.
  394. // Input:    Reference to CoolString object
  395. //           Radix of number
  396. // Output:   Long integer representing value contained in the CoolString
  397.  
  398. long strtol (const CoolString& s, char** ptr, int radix) {
  399.   return (strtol ((char *)s.str, ptr, radix)); 
  400. }    
  401.  
  402.  
  403. // atol -- Equivalent to: strtol (str, (char**)END_OF_STRING, 10)
  404. // Input:  Reference to CoolString object
  405. // Output: Long integer representing value contained in the CoolString
  406.  
  407. long atol (const CoolString& s) {        // Convert string to long
  408.   return (strtol ((char *)s.str, (char **) END_OF_STRING, int(10)));
  409. }
  410.  
  411.  
  412. // atoi -- Equivalent to: (int)strtol (str, (char**)END_OF_STRING, 10)
  413. // Input:  Reference to CoolString object
  414. // Output: Integer representing value contained in the CoolString
  415.  
  416. int atoi (const CoolString& s) {        // Convert string to int
  417.   return int(strtol ((char *)s.str, (char **) END_OF_STRING, int(10)));    
  418. }
  419.  
  420.  
  421. // strtod -- Returns as a double-precision floating-point number the
  422. //           value represented by a CoolString object. Characters are
  423. //           scanned upto the first unrecognized character.
  424. // Input:    Reference to CoolString object
  425. // Output:   Double representing value contained in CoolString
  426.  
  427. double strtod (const CoolString& s, char** ptr) {    // Convert string to double
  428.   return (strtod ((char *)s.str, ptr));
  429. }
  430.  
  431.  
  432. // trim -- Removes any occurrence of the character(s) in "c" from "s"
  433. // Input:  Simople_CoolString reference, character string
  434. // Output: Modified CoolString "s" object
  435.  
  436. CoolString& trim (CoolString& sr, const char* rem) {
  437.   char* s = sr.str;
  438.   char* result = sr.str;
  439.   long len = 0;
  440.   register char c;
  441.   while ((c=*s++) != END_OF_STRING) {
  442.     register const char* r = rem;
  443.     register char t;
  444.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  445.     if (t == END_OF_STRING)             // If no match found
  446.       *result++ = c, len++;
  447.   }
  448.   *result = END_OF_STRING;            // NULL terminate string
  449.   sr.length = len;
  450.   return sr;                    // Return string
  451. }
  452.  
  453.  
  454. // left_trim -- Removes any occurrence of the character(s) in "c" from
  455. //              "s" that appear as a prefix to the string. The first
  456. //              non-matching character encountered terminates the remove
  457. //              operation and the rest of the string is copied intact.
  458. // Input:       CoolString reference, character string
  459. // Output:      Modified CoolString "s" object
  460.  
  461. CoolString& left_trim (CoolString& sr, const char* rem) { // Trim prefix from CoolString
  462.   char* result = sr.str;
  463.   char* s = sr.str;
  464.   long len = 0;
  465.   register char c;
  466.   for (; (c=*s) != END_OF_STRING; s++) {
  467.     register const char* r = rem;
  468.     register char t;
  469.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  470.     if (t == END_OF_STRING)             // If no match found
  471.       break;
  472.   }
  473.   if (s != result)                  // when characters trimed
  474.     while ((*result++ = *s++) != END_OF_STRING) len++; // shift string down
  475.   sr.length = len;
  476.   return sr;                // Return string reference
  477. }
  478.  
  479.  
  480. // right_trim -- Removes any occurrence of the character(s) in "c" from
  481. //               "s" that appear as a suffix to the string. The first
  482. //               non-matching character encountered terminates the remove
  483. //               operation and the rest of the string is copied intact.
  484. // Input:        CoolString reference, character string
  485. // Output:       Modified CoolString "s" object
  486.  
  487. CoolString& right_trim (CoolString& sr, const char* rem) {
  488.   char* str = sr.str;
  489.   char* s = str + strlen(str) - 1;        // last character of string
  490.   for (; s >= str; s--) {
  491.     register const char* r = rem;
  492.     register char t;
  493.     register char c = *s;
  494.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  495.     if (t == END_OF_STRING)             // If no match found
  496.       break;
  497.   }
  498.   *(s+1) = END_OF_STRING;
  499.   sr.length = s - str;
  500.   return sr;                // Return CoolString reference
  501. }
  502.  
  503.  
  504. // upcase -- Convert all alphabetical characters to uppercase
  505. // Input:    CoolString reference
  506. // Output:   Updated string
  507.  
  508. CoolString& upcase (CoolString& s) {    // Convert entire string to upper case
  509.   c_upcase(s.str);
  510.   return s;            // Return reference to modified string
  511. }
  512.  
  513.  
  514. // downcase -- Convert all alphabetical characters to lowercase
  515. // Input:      CoolString reference
  516. // Output:     Updated string
  517.  
  518. CoolString& downcase (CoolString& s) {    // Convert entire string to lower case
  519.   c_downcase(s.str);
  520.   return s;            // Return reference to modified string
  521. }
  522.  
  523. // capitalize -- Capitalize all words in a CoolString. A word is define as
  524. //               a sequence of characters separated by non alphanumerics
  525. // Input:        CoolString reference
  526. // Output:       Updated string
  527.  
  528. CoolString& capitalize (CoolString& s) {    // Capitalize each word in string
  529.   c_capitalize(s.str);
  530.   return s;            // Return reference to modified string
  531. }
  532.  
  533.  
  534. // insert -- Insert a char* at the position specified by start.
  535. // Input  -- A char* to be inserted and a long index.          
  536. // Output -- A Boolean, true if insertion took place, false if error.
  537.  
  538. Boolean CoolString::insert (const char* ins, long start) {
  539.   if (start<0 || start>this->length) return(FALSE);  // Boundary check
  540.   long len=strlen(ins);                 // length of char*
  541.   this->length += len;              // Determine length of new string
  542.   if (this->size <= this->length)    // If not enough allocated memory
  543.     update_memory (*this);        // Adjust/update memory if necessary
  544.   register char* ptr = this->str;
  545.   register char* st = ptr + start;
  546.   register char* end = ptr + this->length;
  547.   for (ptr = end - len; ptr >= st;)        // Make space for ins
  548.     *end-- = *ptr--;
  549.   for (end = st+len; st < end; *st++ = *ins++);    // Insert ins into that
  550.   return(TRUE);                // Insert worked
  551. }
  552.  
  553.  
  554. // remove -- Removes everything between the start and end indexes of string
  555. //           The character at start is removed and all characters up to but 
  556. //           not including the character at end.
  557. // Input  -- A start and end index into the string.
  558. // Output -- A Boolean, true if remove worked, false if error.
  559.  
  560. Boolean CoolString::remove (long start, long end) {
  561.   if (start<0 || start > this->length || end<0    // Boundary check
  562.       || end > this->length || end<=start)
  563.     return(FALSE);                // Out of bounds, failure
  564.   this->length -= (end-start);            // New (shorter) length
  565.   for(; this->str[start]=this->str[end]; start++) end++; // Remove everything
  566.   return(TRUE);                                 // Remove worked
  567. }
  568.  
  569.  
  570. // replace -- Removes everything between start and end as in remove(), and
  571. //            inserts the char* argument into the place of what was removed.
  572. // Input   -- A start and end for remove and a char*, c, to insert.
  573. // Output  -- A Boolean, true if replace worked, false if error.
  574.  
  575. Boolean CoolString::replace (const char* c, long start, long end) {
  576.   if (start<0 || start > this->length || end<0    // Boundary check
  577.       || end > this->length || end<=start)    // out of bounds, failure
  578.     return(FALSE); 
  579.   long len=strlen(c);                   // length of c
  580.   long delta = len - end + start;    // find overall change in length
  581.   this->length += delta;        // set new length
  582.   if (this->size <= this->length)    // If not enough allocated memory
  583.     update_memory (*this);        // Adjust/update memory if necessary
  584.   long ind;
  585.   if (delta > 0) {                      // If replacement is bigger
  586.     for (ind=this->length; start+len<=ind; ind--) // than chacters replaced
  587.       this->str[ind] = this->str[ind-delta];
  588.   }
  589.   else if (delta < 0) {          // Replacement is shorter
  590.     char* st = this->str + start + len;
  591.     char* ptr = this->str + end;
  592.     char* end = this->str + this->length;
  593.     while (st<=end) *st++ = *ptr++;
  594.   }
  595.   { char* ptr = this->str+start;
  596.     char ch;
  597.     while ((ch = *c++) != END_OF_STRING) // replace characters
  598.       *ptr++ = ch;
  599.   }
  600.   return(TRUE);
  601. }
  602.  
  603.  
  604. // yank   -- Removes everything between start and end, copies it into a 
  605. //           a string and returns that string.
  606. // Input  -- A reference to a CoolString.  A start and end for the remove.
  607. // Output -- none.  Sets the CoolString.
  608.  
  609. void CoolString::yank (CoolString& s, long start, long end) {
  610. #if ERROR_CHECKING
  611.   if (start < 0 || start > this->length || end < 0    // Boundary check
  612.       || end > this->length || end <= start) {
  613.     printf ("CoolString::sub_yank(): Start %d and/or end %d index invalid.\n",
  614.         start, end);
  615.     exit (1);
  616.   }
  617. #endif
  618.   long len = end - start;
  619.   strncpy(s, this->str+start, len);    // Copy stuff to yank into s
  620.   this->length -= len;            // set new length
  621.   for(; this->str[start]=this->str[end]; start++) end++;  // Do the remove
  622. }
  623.  
  624.  
  625. // sub_string -- Returns a new string initialized to what is between the
  626. //               start and end indexes.
  627. // Input      -- A reference to a String.  Two longs, a start and an end
  628. // Output     -- none.  Sets the CoolString.
  629.  
  630. void CoolString::sub_string (CoolString& s, long start, long end) {
  631. #if ERROR_CHECKING
  632.   if (start < 0 || start > this->length || end < 0    // Boundary check
  633.       || end > this->length || end <= start) {
  634.     printf ("CoolString::sub_string(): Start %d and/or end %d index invalid.\n",
  635.         start, end);
  636.     exit (1);
  637.   }
  638. #endif
  639.   strncpy(s, this->str+start, end - start);    // Copy substring into s
  640. }
  641.  
  642.  
  643. // strncpy -- Returns s, with the first length characters of source copied
  644. //            into it.  The old value of s is lost.
  645. // Input   -- A reference to a CoolString s, a char* source, and a long length.
  646. // Output  -- The modified CoolString s.
  647.  
  648. CoolString& strncpy(CoolString& s, const char* source, long length) {
  649. #if ERROR_CHECKING
  650.   if (length < 0) {            // Boundary check
  651.     printf ("CoolString::strncpy(): Negative length %d.\n", length);
  652.     exit (1);
  653.   }
  654. #endif
  655.   s.length = length;            // Set new string length
  656.   if (s.size <= length)    {        // If not enough allocated memory
  657.     if (s.str) *s.str = END_OF_STRING;    // Don't copy old string
  658.     update_memory (s);            // Adjust/update memory if necessary
  659.   }
  660.   char* p = s.str;
  661.   while (length-- > 0)            // Copy source into string
  662.     *p++ = *source++;
  663.   *p = END_OF_STRING;            // set the end byte
  664.   return s;
  665. }
  666.  
  667.  
  668. // bracket_error -- Raise exception for operator[]
  669. // Input:           Index value
  670. // Output:          None
  671.  
  672. void CoolString::bracket_error (long n) {
  673.   printf ("CoolString::operator[](): Index %d out of range.\n", n);
  674.   exit (1);
  675. }
  676.  
  677.  
  678. // growth_error -- Raise exception for set_alloc_size()
  679. // Input:          Growth value
  680. // Output:         None
  681.  
  682. void CoolString::growth_error (int i) {
  683.   printf ("CoolString::set_alloc_size(): Negative growth size %d.\n", i);
  684.   exit (1);
  685. }
  686.  
  687. // ratio_error -- Raise exception for set_growth_ratio()
  688. // Input:         Growth ration
  689. // Output:        None
  690.  
  691. void CoolString::ratio_error (float ratio) {
  692.   printf ("CoolString::set_growth_ratio(): Negative growth ratio %f.\n", ratio);
  693.   exit (1);
  694. }
  695.  
  696. int CoolString::alloc_size_s = 0;
  697.